home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
gnu
/
include
/
incl98.zoo
/
math-68881.h
< prev
next >
Wrap
C/C++ Source or Header
|
1994-02-22
|
11KB
|
604 lines
/******************************************************************\
* *
* <math-68881.h> last modified: 23 May 1992. *
* *
* Copyright (C) 1989 by Matthew Self. *
* You may freely distribute verbatim copies of this software *
* provided that this copyright notice is retained in all copies. *
* You may distribute modifications to this software under the *
* conditions above if you also clearly note such modifications *
* with their author and date. *
* *
* Note: errno is not set to EDOM when domain errors occur for *
* most of these functions. Rather, it is assumed that the *
* 68881's OPERR exception will be enabled and handled *
* appropriately by the operating system. Similarly, overflow *
* and underflow do not set errno to ERANGE. *
* *
* Send bugs to Matthew Self (self@bayes.arc.nasa.gov). *
* *
\******************************************************************/
/* This file is NOT a part of GCC, just distributed with it. */
/* If you find this in GCC,
please send bug reports to bug-gcc@prep.ai.mit.edu. */
/* Changed by Richard Stallman:
May 1993, add conditional to prevent multiple inclusion.
% inserted before a #.
New function `hypot' added.
Nans written in hex to avoid 0rnan.
May 1992, use %! for fpcr register. Break lines before function names.
December 1989, add parens around `&' in pow.
November 1990, added alternate definition of HUGE_VAL for Sun. */
#ifndef __math_68881
#define __math_68881
#include <errno.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef HUGE_VAL
#ifdef __sun__
/* The Sun assembler fails to handle the hex constant in the usual defn. */
#define HUGE_VAL \
({ \
static union { int i[2]; double d; } u = { {0x7ff00000, 0} }; \
u.d; \
})
#else
#define HUGE_VAL \
({ \
double huge_val; \
\
__asm ("fmove%.d %#0x7ff0000000000000,%0" /* Infinity */ \
: "=f" (huge_val) \
: /* no inputs */); \
huge_val; \
})
#endif
#endif
#if __GNUC__ > 2 || __GCC_MINOR__ >= 5
#define __const_attribute __attribute ((const))
#else
#define __const_attribute
#endif
__inline static double
sin (double x) __const_attribute;
__inline static double
sin (double x)
{
double value;
__asm ("fsin%.x %1,%0"
: "=f" (value)
: "f" (x));
return value;
}
__inline static double
cos (double x) __const_attribute;
__inline static double
cos (double x)
{
double value;
__asm ("fcos%.x %1,%0"
: "=f" (value)
: "f" (x));
return value;
}
__inline static double
tan (double x) __const_attribute;
__inline static double
tan (double x)
{
double value;
__asm ("ftan%.x %1,%0"
: "=f" (value)
: "f" (x));
return value;
}
__inline static double
asin (double x) __const_attribute;
__inline static double
asin (double x)
{
double value;
__asm ("fasin%.x %1,%0"
: "=f" (value)
: "f" (x));
return value;
}
__inline static double
acos (double x) __const_attribute;
__inline static double
acos (double x)
{
double value;
__asm ("facos%.x %1,%0"
: "=f" (value)
: "f" (x));
return value;
}
__inline static double
atan (double x) __const_attribute;
__inline static double
atan (double x)
{
double value;
__asm ("fatan%.x %1,%0"
: "=f" (value)
: "f" (x));
return value;
}
__inline static double
atan2 (double y, double x) __const_attribute;
__inline static double
atan2 (double y, double x)
{
double pi, pi_over_2;
__asm ("fmovecr%.x %#0,%0" /* extended precision pi */
: "=f" (pi)
: /* no inputs */ );
__asm ("fscale%.b %#-1,%0" /* no loss of accuracy */
: "=f" (pi_over_2)
: "0" (pi));
if (x > 0)
{
if (y > 0)
{
if (x > y)
return atan (y / x);
else
return pi_over_2 - atan (x / y);
}
else
{
if (x > -y)
return atan (y / x);
else
return - pi_over_2 - atan (x / y);
}
}
else
{
if (y < 0)
{
if (-x > -y)
return - pi + atan (y / x);
else
return - pi_over_2 - atan (x / y);
}
else
{
if (-x > y)
return pi + atan (y / x);
else if (y > 0)
return pi_over_2 - atan (x / y);
else
{
double value;
errno = EDOM;
__asm ("fmove%.d %#0x7fffffffffffffff,%0" /* quiet NaN */
: "=f" (value)
: /* no inputs */);
return value;
}
}
}
}
__inline static double
sinh (double x) __const_attribute;
__inline static double
sinh (double x)
{
double value;
__asm ("fsinh%.x %1,%0"
: "=f" (value)
: "f" (x));
return value;
}
__inline static double
cosh (double x) __const_attribute;
__inline static double
cosh (double x)
{
double value;
__asm ("fcosh%.x %1,%0"
: "=f" (value)
: "f" (x));
return value;
}
__inline static double
tanh (double x) __const_attribute;
__inline static double
tanh (double x)
{
double value;
__asm ("ftanh%.x %1,%0"
: "=f" (value)
: "f" (x));
return value;
}
__inline static double
atanh (double x) __const_attribute;
__inline static double
atanh (double x)
{
double value;
__asm ("fatanh%.x %1,%0"
: "=f" (value)
: "f" (x));
return value;
}
__inline static double
exp (double x) __const_attribute;
__inline static double
exp (double x)
{
double value;
__asm ("fetox%.x %1,%0"
: "=f" (value)
: "f" (x));
return value;
}
__inline static double
expm1 (double x) __const_attribute;
__inline static double
expm1 (double x)
{
double value;
__asm ("fetoxm1%.x %1,%0"
: "=f" (value)
: "f" (x));
return value;
}
__inline static double
log (double x) __const_attribute;
__inline static double
log (double x)
{
double value;
__asm ("flogn%.x %1,%0"
: "=f" (value)
: "f" (x));
return value;
}
__inline static double
log1p (double x) __const_attribute;
__inline static double
log1p (double x)
{
double value;
__asm ("flognp1%.x %1,%0"
: "=f" (value)
: "f" (x));
return value;
}
__inline static double
log10 (double x) __const_attribute;
__inline static double
log10 (double x)
{
double value;
__asm ("flog10%.x %1,%0"
: "=f" (value)
: "f" (x));
return value;
}
__inline static double
sqrt (double x) __const_attribute;
__inline static double
sqrt (double x)
{
double value;
__asm ("fsqrt%.x %1,%0"
: "=f" (value)
: "f" (x));
return value;
}
__inline static double
hypot (const double x, const double y) __const_attribute;
__inline static double
hypot (const double x, const double y)
{
#if 0
return sqrt (x*x + y*y);
#else
double value;
__asm ("fsqrt%.x %1,%0"
: "=f" (value)
: "f" (x*x + y*y));
return value;
#endif
}
__inline static double
pow (const double x, const double y) __const_attribute;
__inline static double
pow (const double x, const double y)
{
if (x > 0)
return exp (y * log (x));
else if (x == 0)
{
if (y > 0)
return 0.0;
else
{
double value;
errno = EDOM;
__asm ("fmove%.d %#0x7fffffffffffffff,%0" /* quiet NaN */
: "=f" (value)
: /* no inputs */);
return value;
}
}
else
{
double temp;
__asm ("fintrz%.x %1,%0"
: "=f" (temp) /* integer-valued float */
: "f" (y));
if (y == temp)
{
int i = (int) y;
if ((i & 1) == 0) /* even */
return exp (y * log (-x));
else
return - exp (y * log (-x));
}
else
{
double value;
errno = EDOM;
__asm ("fmove%.d %#0x7fffffffffffffff,%0" /* quiet NaN */
: "=f" (value)
: /* no inputs */);
return value;
}
}
}
__inline static double
fabs (double x) __const_attribute;
__inline static double
fabs (double x)
{
double value;
__asm ("fabs%.x %1,%0"
: "=f" (value)
: "f" (x));
return value;
}
__inline static double
ceil (double x) __const_attribute;
__inline static double
ceil (double x)
{
int rounding_mode, round_up;
double value;
__asm volatile ("fmove%.l %!,%0"
: "=dm" (rounding_mode)
: /* no inputs */ );
round_up = rounding_mode | 0x30;
__asm volatile ("fmove%.l %0,%!"
: /* no outputs */
: "dmi" (round_up));
__asm volatile ("fint%.x %1,%0"
: "=f" (value)
: "f" (x));
__asm volatile